package com.polaris.live.utils.zego.core

import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.blankj.utilcode.util.GsonUtils
import com.polaris.live.common.util.LogExt
import com.polaris.live.common.util.StructUtils
import com.polaris.live.utils.zego.LiveEngineManage
import im.zego.zegoexpress.callback.IZegoEventHandler
import im.zego.zegoexpress.constants.ZegoAudioRoute
import im.zego.zegoexpress.constants.ZegoAudioVADStableStateMonitorType
import im.zego.zegoexpress.constants.ZegoAudioVADType
import im.zego.zegoexpress.constants.ZegoDeviceExceptionType
import im.zego.zegoexpress.constants.ZegoDeviceType
import im.zego.zegoexpress.constants.ZegoEngineState
import im.zego.zegoexpress.constants.ZegoNetworkMode
import im.zego.zegoexpress.constants.ZegoNetworkSpeedTestType
import im.zego.zegoexpress.constants.ZegoObjectSegmentationState
import im.zego.zegoexpress.constants.ZegoPlayerMediaEvent
import im.zego.zegoexpress.constants.ZegoPlayerState
import im.zego.zegoexpress.constants.ZegoPublishChannel
import im.zego.zegoexpress.constants.ZegoPublisherState
import im.zego.zegoexpress.constants.ZegoRemoteDeviceState
import im.zego.zegoexpress.constants.ZegoRoomState
import im.zego.zegoexpress.constants.ZegoRoomStateChangedReason
import im.zego.zegoexpress.constants.ZegoScreenCaptureExceptionType
import im.zego.zegoexpress.constants.ZegoStreamEvent
import im.zego.zegoexpress.constants.ZegoStreamQualityLevel
import im.zego.zegoexpress.constants.ZegoSuperResolutionState
import im.zego.zegoexpress.constants.ZegoUpdateType
import im.zego.zegoexpress.constants.ZegoVideoCodecID
import im.zego.zegoexpress.entity.ZegoBarrageMessageInfo
import im.zego.zegoexpress.entity.ZegoBroadcastMessageInfo
import im.zego.zegoexpress.entity.ZegoNetworkSpeedTestQuality
import im.zego.zegoexpress.entity.ZegoPerformanceStatus
import im.zego.zegoexpress.entity.ZegoPlayStreamQuality
import im.zego.zegoexpress.entity.ZegoPublishStreamQuality
import im.zego.zegoexpress.entity.ZegoRoomExtraInfo
import im.zego.zegoexpress.entity.ZegoSoundLevelInfo
import im.zego.zegoexpress.entity.ZegoStream
import im.zego.zegoexpress.entity.ZegoStreamRelayCDNInfo
import im.zego.zegoexpress.entity.ZegoUser
import org.json.JSONObject

/**
 * EventHandlerHelper
 *
 * @author Created by lucas on 2023/10/17 19:59
 */
class EventHandlerHelper : IZegoEventHandler() {

    private val eventHandler = StructUtils.newSaleSet<IZegoEventHandler>()

    /**
     * 观察请求，会自动取消
     */
    fun observe(owner: LifecycleOwner, handler: IZegoEventHandler) {
        if (owner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            return
        }

        eventHandler.add(handler)

        owner.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    eventHandler.remove(handler)
                }
            }
        })
    }

    /**
     * 添加事件监听，注意使用[removeEventHandler]取消监听
     */
    fun addEventHandler(handler: IZegoEventHandler) {
        eventHandler.add(handler)
    }

    /**
     * 删除事件监听
     */
    fun removeEventHandler(handler: IZegoEventHandler) {
        eventHandler.remove(handler)
    }

    override fun onDebugError(errorCode: Int, funcName: String?, info: String?) {
        eventHandler.forEach { it.onDebugError(errorCode, funcName, info) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onDebugError errorCode $errorCode, funcName $funcName, info $info"
        }
    }

    override fun onEngineStateUpdate(state: ZegoEngineState?) {
        eventHandler.forEach { it.onEngineStateUpdate(state) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onEngineStateUpdate state ${state?.value()}"
        }
    }

    override fun onRecvExperimentalAPI(content: String?) {
        eventHandler.forEach { it.onRecvExperimentalAPI(content) }


        LogExt.logI(LiveEngineManage.TAG) {
            "onRecvExperimentalAPI state $content"
        }
    }

    override fun onFatalError(errorCode: Int) {
        eventHandler.forEach { it.onFatalError(errorCode) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onFatalError errorCode $errorCode"
        }
    }

    override fun onRoomStateUpdate(
        roomID: String?,
        state: ZegoRoomState?,
        errorCode: Int,
        extendedData: JSONObject?
    ) {
        eventHandler.forEach { it.onRoomStateUpdate(roomID, state, errorCode, extendedData) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStateUpdate roomID $roomID, state $state, errorCode $errorCode, extendedData $extendedData"
        }
    }

    override fun onRoomStateChanged(
        roomID: String?,
        reason: ZegoRoomStateChangedReason?,
        errorCode: Int,
        extendedData: JSONObject?
    ) {
        eventHandler.forEach { it.onRoomStateChanged(roomID, reason, errorCode, extendedData) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStateUpdate roomID $roomID, reason ${reason?.value()}, errorCode $errorCode, extendedData $extendedData"
        }
    }

    override fun onRoomUserUpdate(
        roomID: String?,
        updateType: ZegoUpdateType?,
        userList: ArrayList<ZegoUser>?
    ) {
        eventHandler.forEach { it.onRoomUserUpdate(roomID, updateType, userList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStateUpdate roomID $roomID, updateType ${updateType?.value()}, userList ${
                userList?.let {
                    GsonUtils.toJson(it)
                }
            }"
        }
    }

    override fun onRoomOnlineUserCountUpdate(roomID: String?, count: Int) {
        eventHandler.forEach { it.onRoomOnlineUserCountUpdate(roomID, count) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomOnlineUserCountUpdate roomID $roomID, count $count"
        }
    }

    override fun onRoomStreamUpdate(
        roomID: String?,
        updateType: ZegoUpdateType?,
        streamList: ArrayList<ZegoStream>?,
        extendedData: JSONObject?
    ) {
        eventHandler.forEach { it.onRoomStreamUpdate(roomID, updateType, streamList, extendedData) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStreamUpdate roomID $roomID, updateType ${updateType?.value()}, streamList ${
                streamList?.let {
                    GsonUtils.toJson(
                        it
                    )
                }
            }, extendedData $extendedData"
        }
    }

    override fun onRoomStreamExtraInfoUpdate(roomID: String?, streamList: ArrayList<ZegoStream>?) {
        eventHandler.forEach { it.onRoomStreamExtraInfoUpdate(roomID, streamList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStreamExtraInfoUpdate roomID $roomID, streamList ${streamList?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onRoomExtraInfoUpdate(
        roomID: String?,
        roomExtraInfoList: ArrayList<ZegoRoomExtraInfo>?
    ) {
        eventHandler.forEach { it.onRoomExtraInfoUpdate(roomID, roomExtraInfoList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRoomStreamExtraInfoUpdate roomID $roomID, roomExtraInfoList ${
                roomExtraInfoList?.let {
                    GsonUtils.toJson(
                        it
                    )
                }
            }"
        }
    }

    override fun onRoomTokenWillExpire(roomID: String?, remainTimeInSecond: Int) {
        eventHandler.forEach { it.onRoomTokenWillExpire(roomID, remainTimeInSecond) }
    }

    override fun onPublisherStateUpdate(
        streamID: String?,
        state: ZegoPublisherState?,
        errorCode: Int,
        extendedData: JSONObject?
    ) {
        eventHandler.forEach { it.onPublisherStateUpdate(streamID, state, errorCode, extendedData) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherStateUpdate streamID $streamID, state ${state?.value()}, errorCode $errorCode, extendedData $extendedData"
        }
    }

    override fun onPublisherQualityUpdate(streamID: String?, quality: ZegoPublishStreamQuality?) {
        eventHandler.forEach { it.onPublisherQualityUpdate(streamID, quality) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherQualityUpdate streamID $streamID, quality ${quality?.let { GsonUtils.toJson(quality) }}"
        }
    }

    override fun onPublisherCapturedAudioFirstFrame() {
        eventHandler.forEach { it.onPublisherCapturedAudioFirstFrame() }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherCapturedAudioFirstFrame"
        }
    }

    override fun onPublisherCapturedVideoFirstFrame(channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherCapturedVideoFirstFrame(channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherCapturedVideoFirstFrame channel ${channel?.value()}"
        }
    }

    override fun onPublisherSendAudioFirstFrame(channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherSendAudioFirstFrame(channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherSendAudioFirstFrame channel ${channel?.value()}"
        }
    }

    override fun onPublisherSendVideoFirstFrame(channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherSendVideoFirstFrame(channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherSendVideoFirstFrame channel ${channel?.value()}"
        }
    }

    override fun onPublisherRenderVideoFirstFrame(channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherRenderVideoFirstFrame(channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherRenderVideoFirstFrame channel ${channel?.value()}"
        }
    }

    override fun onPublisherVideoSizeChanged(width: Int, height: Int, channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherVideoSizeChanged(width, height, channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherVideoSizeChanged width $width, height $height, channel ${channel?.value()}"
        }
    }

    override fun onPublisherRelayCDNStateUpdate(
        streamID: String?,
        infoList: ArrayList<ZegoStreamRelayCDNInfo>?
    ) {
        eventHandler.forEach { it.onPublisherRelayCDNStateUpdate(streamID, infoList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherRelayCDNStateUpdate streamID $streamID, infoList ${infoList?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onPublisherVideoEncoderChanged(
        fromCodecID: ZegoVideoCodecID?,
        toCodecID: ZegoVideoCodecID?,
        channel: ZegoPublishChannel?
    ) {
        eventHandler.forEach { it.onPublisherVideoEncoderChanged(fromCodecID, toCodecID, channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherVideoEncoderChanged fromCodecID ${fromCodecID?.value()}, toCodecID ${toCodecID?.value()}, channel ${channel?.value()}"
        }
    }

    override fun onPublisherStreamEvent(eventID: ZegoStreamEvent?, streamID: String?, extraInfo: String?) {
        eventHandler.forEach { it.onPublisherStreamEvent(eventID, streamID, extraInfo) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherStreamEvent eventID ${eventID?.value()}, streamID $streamID, extraInfo $extraInfo"
        }
    }

    override fun onVideoObjectSegmentationStateChanged(
        state: ZegoObjectSegmentationState?,
        channel: ZegoPublishChannel?,
        errorCode: Int
    ) {
        eventHandler.forEach { it.onVideoObjectSegmentationStateChanged(state, channel, errorCode) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onVideoObjectSegmentationStateChanged state ${state?.value()}, channel ${channel?.value()}, errorCode $errorCode"
        }
    }

    override fun onPublisherLowFpsWarning(codecID: ZegoVideoCodecID?, channel: ZegoPublishChannel?) {
        eventHandler.forEach { it.onPublisherLowFpsWarning(codecID, channel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPublisherLowFpsWarning codecID ${codecID?.value()}, channel ${channel?.value()}"
        }
    }

    override fun onPlayerStateUpdate(
        streamID: String?,
        state: ZegoPlayerState?,
        errorCode: Int,
        extendedData: JSONObject?
    ) {
        eventHandler.forEach { it.onPlayerStateUpdate(streamID, state, errorCode, extendedData) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerStateUpdate streamID $streamID, state ${state?.value()}, errorCode $errorCode, extendedData ${
                extendedData?.let {
                    GsonUtils.toJson(
                        it
                    )
                }
            }"
        }
    }

    override fun onPlayerQualityUpdate(streamID: String?, quality: ZegoPlayStreamQuality?) {
        eventHandler.forEach { it.onPlayerQualityUpdate(streamID, quality) }
        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerQualityUpdate streamID $streamID, quality ${quality?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onPlayerMediaEvent(streamID: String?, event: ZegoPlayerMediaEvent?) {
        eventHandler.forEach { it.onPlayerMediaEvent(streamID, event) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerMediaEvent streamID $streamID, event ${event?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onPlayerRecvAudioFirstFrame(streamID: String?) {
        eventHandler.forEach { it.onPlayerRecvAudioFirstFrame(streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRecvAudioFirstFrame streamID $streamID"
        }
    }

    override fun onPlayerRecvVideoFirstFrame(streamID: String?) {
        eventHandler.forEach { it.onPlayerRecvVideoFirstFrame(streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRecvVideoFirstFrame streamID $streamID"
        }
    }

    override fun onPlayerSyncRecvVideoFirstFrame(streamID: String?) {
        eventHandler.forEach { it.onPlayerSyncRecvVideoFirstFrame(streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerSyncRecvVideoFirstFrame streamID $streamID"
        }
    }

    override fun onPlayerRenderVideoFirstFrame(streamID: String?) {
        eventHandler.forEach { it.onPlayerRenderVideoFirstFrame(streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRenderVideoFirstFrame streamID $streamID"
        }
    }

    override fun onPlayerRenderCameraVideoFirstFrame(streamID: String?) {
        eventHandler.forEach { it.onPlayerRenderCameraVideoFirstFrame(streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRenderCameraVideoFirstFrame streamID $streamID"
        }
    }

    override fun onPlayerVideoSizeChanged(streamID: String?, width: Int, height: Int) {
        eventHandler.forEach { it.onPlayerVideoSizeChanged(streamID, width, height) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerVideoSizeChanged streamID $streamID, width $width, height $height"
        }
    }

    override fun onPlayerRecvSEI(streamID: String?, data: ByteArray?) {
        eventHandler.forEach { it.onPlayerRecvSEI(streamID, data) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRecvSEI streamID $streamID, dataSize ${data?.size}"
        }
    }

    override fun onPlayerSyncRecvSEI(streamID: String?, data: ByteArray?) {
        eventHandler.forEach { it.onPlayerSyncRecvSEI(streamID, data) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerSyncRecvSEI streamID $streamID, dataSize ${data?.size}"
        }
    }

    override fun onPlayerRecvAudioSideInfo(streamID: String?, data: ByteArray?) {
        eventHandler.forEach { it.onPlayerRecvAudioSideInfo(streamID, data) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerRecvAudioSideInfo streamID $streamID, dataSize ${data?.size}"
        }
    }

    override fun onPlayerLowFpsWarning(codecID: ZegoVideoCodecID?, streamID: String?) {
        eventHandler.forEach { it.onPlayerLowFpsWarning(codecID, streamID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerLowFpsWarning codecID ${codecID?.value()}, streamID $streamID"
        }
    }

    override fun onPlayerStreamEvent(eventID: ZegoStreamEvent?, streamID: String?, extraInfo: String?) {
        eventHandler.forEach { it.onPlayerStreamEvent(eventID, streamID, extraInfo) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerStreamEvent eventID ${eventID?.value()}, streamID $streamID, extraInfo $extraInfo"
        }
    }

    override fun onPlayerVideoSuperResolutionUpdate(
        streamID: String?,
        state: ZegoSuperResolutionState?,
        errorCode: Int
    ) {
        eventHandler.forEach { it.onPlayerVideoSuperResolutionUpdate(streamID, state, errorCode) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPlayerVideoSuperResolutionUpdate streamID $streamID, state ${state?.value()}, errorCode $errorCode"
        }
    }

    override fun onMixerRelayCDNStateUpdate(
        taskID: String?,
        infoList: ArrayList<ZegoStreamRelayCDNInfo>?
    ) {
        eventHandler.forEach { it.onMixerRelayCDNStateUpdate(taskID, infoList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onMixerRelayCDNStateUpdate taskID $taskID, infoList ${infoList?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onMixerSoundLevelUpdate(soundLevels: HashMap<Int, Float>?) {
        eventHandler.forEach { it.onMixerSoundLevelUpdate(soundLevels) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onMixerSoundLevelUpdate soundLevels ${soundLevels?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onAutoMixerSoundLevelUpdate(soundLevels: HashMap<String, Float>?) {
        eventHandler.forEach { it.onAutoMixerSoundLevelUpdate(soundLevels) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onAutoMixerSoundLevelUpdate soundLevels ${soundLevels?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onCapturedSoundLevelUpdate(soundLevel: Float) {
        eventHandler.forEach { it.onCapturedSoundLevelUpdate(soundLevel) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onCapturedSoundLevelUpdate soundLevel $soundLevel"
        }
    }

    override fun onCapturedSoundLevelInfoUpdate(soundLevelInfo: ZegoSoundLevelInfo?) {
        eventHandler.forEach { it.onCapturedSoundLevelInfoUpdate(soundLevelInfo) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onCapturedSoundLevelInfoUpdate soundLevelInfo ${soundLevelInfo?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onRemoteSoundLevelUpdate(soundLevels: HashMap<String, Float>?) {
        eventHandler.forEach { it.onRemoteSoundLevelUpdate(soundLevels) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRemoteSoundLevelUpdate soundLevels ${soundLevels?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onRemoteSoundLevelInfoUpdate(soundLevelInfos: HashMap<String, ZegoSoundLevelInfo>?) {
        eventHandler.forEach { it.onRemoteSoundLevelInfoUpdate(soundLevelInfos) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRemoteSoundLevelInfoUpdate soundLevelInfos ${soundLevelInfos?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onCapturedAudioSpectrumUpdate(audioSpectrum: FloatArray?) {
        eventHandler.forEach { it.onCapturedAudioSpectrumUpdate(audioSpectrum) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onCapturedAudioSpectrumUpdate audioSpectrumSize ${audioSpectrum?.size}"
        }
    }

    override fun onRemoteAudioSpectrumUpdate(audioSpectrums: HashMap<String, FloatArray>?) {
        eventHandler.forEach { it.onRemoteAudioSpectrumUpdate(audioSpectrums) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRemoteAudioSpectrumUpdate audioSpectrums ${audioSpectrums?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onLocalDeviceExceptionOccurred(
        exceptionType: ZegoDeviceExceptionType?,
        deviceType: ZegoDeviceType?,
        deviceID: String?
    ) {
        eventHandler.forEach { it.onLocalDeviceExceptionOccurred(exceptionType, deviceType, deviceID) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onLocalDeviceExceptionOccurred exceptionType ${exceptionType?.value()}, deviceType ${deviceType?.value()}, deviceID $deviceID"
        }
    }

    override fun onRemoteCameraStateUpdate(streamID: String?, state: ZegoRemoteDeviceState?) {
        eventHandler.forEach { it.onRemoteCameraStateUpdate(streamID, state) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onLocalDeviceExceptionOccurred streamID $streamID, state ${state?.value()}"
        }
    }

    override fun onRemoteMicStateUpdate(streamID: String?, state: ZegoRemoteDeviceState?) {
        eventHandler.forEach { it.onRemoteMicStateUpdate(streamID, state) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRemoteMicStateUpdate streamID $streamID, state ${state?.value()}"
        }
    }

    override fun onRemoteSpeakerStateUpdate(streamID: String?, state: ZegoRemoteDeviceState?) {
        eventHandler.forEach { it.onRemoteSpeakerStateUpdate(streamID, state) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onRemoteSpeakerStateUpdate streamID $streamID, state ${state?.value()}"
        }
    }

    override fun onAudioRouteChange(audioRoute: ZegoAudioRoute?) {
        eventHandler.forEach { it.onAudioRouteChange(audioRoute) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onAudioRouteChange audioRoute ${audioRoute?.value()}"
        }
    }

    override fun onAudioVADStateUpdate(type: ZegoAudioVADStableStateMonitorType?, state: ZegoAudioVADType?) {
        eventHandler.forEach { it.onAudioVADStateUpdate(type, state) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onAudioVADStateUpdate type ${type?.value()}, state ${state?.value()}"
        }
    }

    override fun onIMRecvBroadcastMessage(
        roomID: String?,
        messageList: ArrayList<ZegoBroadcastMessageInfo>?
    ) {
        eventHandler.forEach { it.onIMRecvBroadcastMessage(roomID, messageList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onIMRecvBroadcastMessage roomID $roomID, messageList ${messageList?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onIMRecvBarrageMessage(
        roomID: String?,
        messageList: ArrayList<ZegoBarrageMessageInfo>?
    ) {
        eventHandler.forEach { it.onIMRecvBarrageMessage(roomID, messageList) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onIMRecvBarrageMessage roomID $roomID, messageList ${messageList?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onIMRecvCustomCommand(roomID: String?, fromUser: ZegoUser?, command: String?) {
        eventHandler.forEach { it.onIMRecvCustomCommand(roomID, fromUser, command) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onIMRecvCustomCommand roomID $roomID, fromUser ${fromUser?.let { GsonUtils.toJson(it) }}, command $command"
        }
    }

    override fun onPerformanceStatusUpdate(status: ZegoPerformanceStatus?) {
        eventHandler.forEach { it.onPerformanceStatusUpdate(status) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onPerformanceStatusUpdate status ${status?.let { GsonUtils.toJson(it) }}"
        }
    }

    override fun onNetworkModeChanged(mode: ZegoNetworkMode?) {
        eventHandler.forEach { it.onNetworkModeChanged(mode) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onNetworkModeChanged mode ${mode?.value()}"
        }
    }

    override fun onNetworkSpeedTestError(errorCode: Int, type: ZegoNetworkSpeedTestType?) {
        eventHandler.forEach { it.onNetworkSpeedTestError(errorCode, type) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onNetworkSpeedTestError errorCode $errorCode, type ${type?.value()}"
        }
    }

    override fun onNetworkSpeedTestQualityUpdate(
        quality: ZegoNetworkSpeedTestQuality?,
        type: ZegoNetworkSpeedTestType?
    ) {
        eventHandler.forEach { it.onNetworkSpeedTestQualityUpdate(quality, type) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onNetworkSpeedTestQualityUpdate quality ${quality?.let { GsonUtils.toJson(it) }}, type ${type?.value()}"
        }
    }

    override fun onNetworkQuality(
        userID: String?,
        upstreamQuality: ZegoStreamQualityLevel?,
        downstreamQuality: ZegoStreamQualityLevel?
    ) {
        eventHandler.forEach { it.onNetworkQuality(userID, upstreamQuality, downstreamQuality) }
        LogExt.logI(LiveEngineManage.TAG) {
            "onNetworkQuality userID $userID, upstreamQuality ${upstreamQuality?.value()}, downstreamQuality ${downstreamQuality?.value()}"
        }
    }

    override fun onNetworkTimeSynchronized() {
        eventHandler.forEach { it.onNetworkTimeSynchronized() }

        LogExt.logI(LiveEngineManage.TAG) {
            "onNetworkTimeSynchronized"
        }
    }

    override fun onScreenCaptureExceptionOccurred(exceptionType: ZegoScreenCaptureExceptionType?) {
        eventHandler.forEach { it.onScreenCaptureExceptionOccurred(exceptionType) }

        LogExt.logI(LiveEngineManage.TAG) {
            "onScreenCaptureExceptionOccurred exceptionType ${exceptionType?.value()}"
        }

    }
}